using System;

namespace PDUConverter
{
    /// <summary>
    /// Represents an SMS-DELIVER PDU, a received short message.
    /// </summary>
    public class SmsDeliverPdu : IncomingSmsPdu
    {
        private string originatingAddress;
        private byte originatingAddressType;
        private SmsTimestamp scTimestamp;

        /// <summary>
        /// Initializes a new <see cref="T:GsmComm.PduConverter.SmsDeliverPdu" /> instance using default values.
        /// </summary>
        public SmsDeliverPdu()
        {
            base._messageFlags = new SmsDeliverMessageFlags();
            this.originatingAddress = string.Empty;
            this.originatingAddressType = 0;
            this.scTimestamp = SmsTimestamp.None;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:GsmComm.PduConverter.SmsDeliverPdu" /> class
        /// using the specified PDU string.
        /// </summary>
        /// <param name="pdu">The PDU string to convert.</param>
        /// <param name="includesSmscData">Specifies if the string contains
        /// SMSC data octets at the beginning.</param>
        /// <param name="actualLength">Specifies the actual PDU length, that is the length in bytes without
        /// the SMSC header. Set to -1 if unknown.</param>
        /// <remarks>
        /// <para>This constructor assumes that the string contains an <b>SMS-DELIVER</b>
        /// PDU data stream as specified by GSM 07.05.</para>
        /// </remarks>
        public SmsDeliverPdu(string pdu, bool includesSmscData, int actualLength)
        {
            if (pdu == string.Empty)
            {
                throw new ArgumentException("pdu must not be an empty string.");
            }
            bool flag = actualLength >= 0;
            int num = actualLength;
            if (!flag || (num > 0))
            {
                int index = 0;
                if (includesSmscData)
                {
                    string str;
                    byte num3;
                    SmsPdu.DecodeSmscAddress(pdu, ref index, out str, out num3);
                    base.SetSmscAddress(str, num3);
                }
                base._messageFlags = new SmsDeliverMessageFlags(BcdWorker.GetByte(pdu, index++));
                if (flag)
                {
                    num--;
                    if (num <= 0)
                    {
                        return;
                    }
                }
                SmsPdu.DecodeGeneralAddress(pdu, ref index, out this.originatingAddress, out this.originatingAddressType);
                if ((index * 2) >= pdu.Length)
                {
                    this.scTimestamp = SmsTimestamp.None;
                    base.ProtocolID = 0x91;
                    base.DataCodingScheme = 0x89;
                }
                else
                {
                    byte num4;
                    byte[] buffer;
                    base.ProtocolID = BcdWorker.GetByte(pdu, index++);
                    base.DataCodingScheme = BcdWorker.GetByte(pdu, index++);
                    this.scTimestamp = new SmsTimestamp(pdu, ref index);
                    SmsPdu.DecodeUserData(pdu, ref index, out num4, out buffer);
                    base.SetUserData(buffer, num4);
                }
            }
        }

        /// <summary>
        /// Returns the relevant timestamp for the message.
        /// </summary>
        /// <returns>An <see cref="T:GsmComm.PduConverter.SmsTimestamp" /> containing the SMSC timestamp,
        /// the time the message was received by the service center.</returns>
        public override SmsTimestamp GetTimestamp()
        {
            return this.scTimestamp;
        }

        /// <summary>
        /// Converts the value of this instance into a string.
        /// </summary>
        /// <param name="excludeSmscData">If true, excludes the SMSC header.</param>
        /// <returns>The encoded string.</returns>
        /// <remarks>Not implemented, always throws an <see cref="T:System.NotImplementedException" />.</remarks>
        public override string ToString(bool excludeSmscData)
        {
            throw new NotImplementedException("SmsDeliverPdu.ToString() not implemented.");
        }

        /// <summary>
        /// Gets the message flags.
        /// </summary>
        /// <exception cref="T:System.ArgumentNullException">The property is being set
        /// and the value is null.</exception>
        public SmsDeliverMessageFlags MessageFlags
        {
            get
            {
                return (SmsDeliverMessageFlags) base._messageFlags;
            }
        }

        /// <summary>
        /// Gets or sets if there are more messages to send.
        /// </summary>
        public bool MoreMessages
        {
            get
            {
                return this.MessageFlags.MoreMessages;
            }
            set
            {
                this.MessageFlags.MoreMessages = value;
            }
        }

        /// <summary>
        /// Gets or sets the originating address.
        /// </summary>
        /// <remarks>
        /// <para>When setting the property, also the <see cref="P:GsmComm.PduConverter.SmsDeliverPdu.OriginatingAddressType" /> property
        /// will be set, attempting to autodetect the address type.</para>
        /// <para>When getting the property, the address may be extended with address-type
        /// specific prefixes or other chraracters.</para>
        /// </remarks>
        public string OriginatingAddress
        {
            get
            {
                return base.CreateAddressOfType(this.originatingAddress, this.originatingAddressType);
            }
            set
            {
                byte num;
                string str;
                base.FindTypeOfAddress(value, out num, out str);
                this.originatingAddress = str;
                this.originatingAddressType = num;
            }
        }

        /// <summary>
        /// Gets or sets the type of the originating address.
        /// </summary>
        /// <remarks>
        /// <para>Represents the Type-of-Address octets for the originating address of the PDU.</para>
        /// </remarks>
        public byte OriginatingAddressType
        {
            get
            {
                return this.originatingAddressType;
            }
        }

        /// <summary>
        /// Gets or sets if a reply path exists.
        /// </summary>
        public bool ReplyPathExists
        {
            get
            {
                return this.MessageFlags.ReplyPathExists;
            }
            set
            {
                this.MessageFlags.ReplyPathExists = value;
            }
        }

        /// <summary>
        /// Gets or sets the timestamp the message was received by the SC.
        /// </summary>
        public SmsTimestamp SCTimestamp
        {
            get
            {
                return this.scTimestamp;
            }
            set
            {
                this.scTimestamp = value;
            }
        }

        /// <summary>
        /// Gets or sets if a status report was be requested.
        /// </summary>
        public bool StatusReportRequested
        {
            get
            {
                return this.MessageFlags.StatusReportRequested;
            }
            set
            {
                this.MessageFlags.StatusReportRequested = value;
            }
        }

        /// <summary>
        /// Gets or sets if a user data header is present.
        /// </summary>
        public bool UserDataHeaderPresent
        {
            get
            {
                return this.MessageFlags.UserDataHeaderPresent;
            }
            set
            {
                this.MessageFlags.UserDataHeaderPresent = value;
            }
        }
    }
}